/*
 * Rational.h
 *
 *  Created on: 20 Dec 2010
 *      Author: Gilthans
 */

#ifndef RATIONAL_H_
#define RATIONAL_H_

#include <iostream>

namespace rational {

class ZeroDivision{};
class Rational {
	long long numerator, denominator;
	//Simplify the fraction by dividing both elements by their gcd.
	void simplify();
	//Gets the gcd between two integer values
	static long long gcd(long long x, long long y);
	//Returns x to the y power
	static long long pow(long long x, unsigned long long y);
public:
	//If denominator == 0 at any point, a ZeroDivision exception will be thrown.
	//You don't need to handle it, just don't divide by zero:)
	//Note the long long->Rational casting here
	Rational(long long numerator=0, long long denominator=1);
	Rational& operator+=(const Rational& r);
	Rational operator-() const;
	Rational& operator-=(const Rational& r);
	Rational& operator*=(const Rational& r);
	Rational& operator/=(const Rational& r);
	//Returns the inverse of the number
	Rational inverse() const;
	//Returns this to the power of x ((a/b)^x)
	Rational power(long long x) const;

	friend bool operator==(const Rational& r1, const Rational& r2);
	friend bool operator<(const Rational& r1, const Rational& r2);
	friend std::ostream& operator<<(std::ostream& os, const Rational& r);
};

Rational operator+(const Rational& r1, const Rational& r2);
Rational operator-(const Rational& r1, const Rational& r2);
Rational operator*(const Rational& r1, const Rational& r2);
Rational operator/(const Rational& r1, const Rational& r2);
bool operator!=(const Rational& r1, const Rational& r2);
bool operator>=(const Rational& r1, const Rational& r2);
bool operator>(const Rational& r1, const Rational& r2);
bool operator<=(const Rational& r1, const Rational& r2);


}

#endif /* RATIONAL_H_ */
